import com.bourre.log.Logger;
import com.bourre.log.LogLevel;
import com.bourre.data.collections.Map;
import com.bourre.events.ListenerArray;

//	Oregano
import org.omus.data.PropertySet;
import org.omus.data.Property;
import org.omus.util._Error;
import org.omus.core.User;

import net.webbymx.pixgano.events.PropertySetEvent;

class net.webbymx.pixgano.handlers.data.BasicPropertySetHandler
	implements net.webbymx.pixgano.handlers.data.IPropertySetHandler {
/* ****************************************************************************
* PUBLIC STATIC VARIABLES
**************************************************************************** */		
	public static var EVENT_ON_SYNCHRONIZE		: PropertySetEvent =  new PropertySetEvent( "onSynchronize" );
	public static var EVENT_ON_LOAD				: PropertySetEvent = new PropertySetEvent( "onLoad" );

/* ****************************************************************************
* PRIVATE VARIABLES
**************************************************************************** */
	private var _oPS		: PropertySet;
	private var _mE			: Map;
		
		
/* ****************************************************************************
* CONSTRUCTOR
**************************************************************************** */
	function BasicPropertySetHandler( ps :PropertySet ) {
		_oPS = ps;
		_oPS.addListener( this );	
		_mE = new Map();
	}
	
	
	public function getListenerArray( t : PropertySetEvent ) : ListenerArray {
		return _mE.get( t.toString() );
	}
	
	public function listenerArrayExists( t : PropertySetEvent ) : Boolean {
		return _mE.containsKey( t.toString() );
	}	

	
/**
* Listen for the event of the targeted PropertySet. 
* Will received the event if the properties push in the array 
* have been modified
* @param	o		the scope of the function
* @param	func	function to call
* @param	event	event to react to
* @param	prop	properties which has to be modified for the func to be called
*/
	public function addEventListener( event: PropertySetEvent, o, func: String, prop: Array ) : Void {
/*Logger.LOG( "BasicPropertySetHandler :: addEventListener" );
Logger.LOG( "event :" + event.toString() );
Logger.LOG( event.toString() );
Logger.LOG( "o" );
Logger.LOG( o );
Logger.LOG( "func: " + func );
Logger.LOG( "prop" );
Logger.LOG( prop );
*/		if ( !( event instanceof PropertySetEvent ) ) {
			Logger.LOG( "BasicPropertySetHandler :: The event is not a valid event. It should be a PropertySetEvent type. Please use the BasicPropertyHandler static properties", LogLevel.WARN );
		} else {
			if ( !listenerArrayExists( event ) ) _mE.put( event.toString(), new ListenerArray() );
			var a : ListenerArray = getListenerArray( event );
			
			var listener : Object = new Object();
			listener.scope = o;
			listener.func = func;
			listener.prop = prop;
			
			a.insert( listener );
		}
	}
	
	
/**
* Removes passed-in {@code oL} listener that suscribed for passed-in {@code t} event.
* @param o 		Listener object
* @param event	event name ( PropertySetEvent )
*/
//	TODO could remove all the record for this object in ALL the event when passing no PropertySetEvent
	public function removeEventListener(o, event : PropertySetEvent ) : Void {
		if ( listenerArrayExists( event ) ) {
			var a : ListenerArray = getListenerArray( event );
			if ( a.remove( o ) ) {
				if ( a.isEmpty() ) _mE.remove( event.toString() );
			}
		}
	}	
	

/**
* Removes all listeners that suscribed for passed-in {@code t} PropertySetEvent.
* @param t event name ( PropertySetEvent )
*/
	public function removeAllEventListeners( event : PropertySetEvent ) : Void {
		if ( listenerArrayExists( event ) ) _mE.remove( event.toString() );

	}
	
	public function unlink() : Void {
		_oPS.removeListener( this );
	}
	
	
/*	public function onSynchronize (propSet:PropertySet):Void
	{
		Logger.LOG("********* SYNCHRONIZE ");
		Logger.LOG( propSet );
	//	ViewGame( MovieClipHelper.getMovieClipHelper( ViewList.VIEW_GAME ) ).moveOpponentPaddle( Number( propSet.getValue( "paddle_y" ) ) );
	}*/
	
	public function onSynchronize( ps : PropertySet, b : Boolean ) : Void {
		var a : Array = ps.getList();
		var la : ListenerArray = getListenerArray( BasicPropertySetHandler.EVENT_ON_SYNCHRONIZE );
		if ( !la.isEmpty() ) {
			//	Loop into the properties array
			//	loop into the listener to check the properties listeneing
			//	maybe find a bettter way to do that.
			for ( var i : Number = 0; i < a.length; ++ i ) {
				for ( var j : Number = 0; j < la.length; ++j ) {
					for ( var k : Number = 0; k < la[ j ].prop.length; ++k ) {
						if ( Property( a[ i ] ).getName() == la[ j ].prop[ k ] ) {
							la[ j ].scope[ la[ j ].func ] ( ps );
							break;
						}	
					}
				}
			}
		}
	}
	

	public function onLoad( ps : PropertySet ) : Void {
Logger.LOG( "BasicPropertyHandler :: onLoad" );
Logger.LOG( ps );
	}
	public function onError( ps : PropertySet, error : _Error ) : Void {
Logger.LOG( "BasicPropertyHandler :: onError", LogLevel.WARN );
Logger.LOG( error.getDescription(), LogLevel.WARN );
	}
	
/* ****************************************************************************
* CONSTRUCTOR
**************************************************************************** */
	public function setPropertySet( ps : PropertySet ) : Void { 
		_oPS = ps;
		_oPS.addListener( this );
	}
	public function getPropertySet() : PropertySet { return _oPS; }
	
	public function setEventListeners( m : Map ) : Void { _mE = m; }
	public function getEventListeners() : Map { return _mE; }
}
